/*
 * Copyright (C) 2013 gujicheng
 * 
 * Licensed under the GPL License Version 2.0;
 * you may not use this file except in compliance with the License.
 * 
 * If you have any question, please contact me.
 * 
 *************************************************************************
 **                   Author information                                **
 *************************************************************************
 ** Email: gujicheng197@126.com                                         **
 ** QQ   : 29600731                                                     **
 ** Weibo: http://weibo.com/gujicheng197                                **
 *************************************************************************
 */
package com.libra.sinvoice

import com.libra.sinvoice.Buffer.BufferData

/**
 *
 * @ClassName: com.libra.sinvoice.SinGenerator
 * @Description: 正弦波发生器
 * @author zhaokaiqiang
 * @date 2014-11-15 下午2:51:34
 */
class SinGenerator @JvmOverloads constructor(private val sinGeneratorCallback: SinGeneratorCallback?, private val mSampleRate: Int = DEFAULT_SAMPLE_RATE,
                                             private val mBits: Int = DEFAULT_BITS, private val mBufferSize: Int = DEFAULT_BUFFER_SIZE) {

    private var mState: Int = 0

    private var mFilledSize: Int = 0

    interface SinGeneratorCallback {

        fun getGenBuffer(): BufferData?

        fun freeGenBuffer(buffer: BufferData)
    }

    init {

        mFilledSize = 0
        mState = STATE_STOP
    }

    fun stop() {
        if (STATE_START == mState) {
            mState = STATE_STOP
        }
    }

    fun start() {
        if (STATE_STOP == mState) {
            mState = STATE_START
        }
    }

    /**
     * 对数字进行编码
     *
     * @param genRate
     * @param duration
     */
    fun gen(genRate: Int, duration: Int) {
        if (STATE_START == mState) {

            // 定值16384
            val n = mBits / 2
            val totalCount = duration * mSampleRate / 1000
            val per = genRate / mSampleRate.toDouble() * 2.0 * Math.PI
            var d = 0.0

            LogHelper.d(TAG, "per:" + per + "___genRate:" + genRate)
            if (null != sinGeneratorCallback) {
                mFilledSize = 0
                // 获取要编码的数据
                var bufferData: BufferData? = sinGeneratorCallback.getGenBuffer()
                if (null != bufferData) {
                    for (i in 0 until totalCount) {

                        if (STATE_START == mState) {

                            // 算出不同点的正弦值
                            val out = (Math.sin(d) * n).toInt() + 128

                            // 如果填充数量超过了缓冲区的大小，就重置mFilledSize，释放bufferData
                            if (mFilledSize >= mBufferSize - 1) {
                                // free buffer
                                bufferData!!.filledSize = mFilledSize
                                sinGeneratorCallback.freeGenBuffer(bufferData)

                                mFilledSize = 0
                                bufferData = sinGeneratorCallback.getGenBuffer()
                                if (null == bufferData) {
                                    LogHelper.d(TAG, "get null buffer")
                                    break
                                }
                            }

                            // 转码为byte类型并保存，& 0xff是为了防止负数转换出现异常
                            bufferData?.byteData!![mFilledSize++] = (out and 0xff).toByte()
                            if (BITS_16 == mBits) {
                                bufferData.byteData!![mFilledSize++] = (out shr 8 and 0xff).toByte()
                            }

                            d += per
                        } else {
                            LogHelper.d(TAG, "sin gen force stop")
                            break
                        }
                    }
                } else {
                    LogHelper.d(TAG, "get null buffer")
                }

                if (null != bufferData) {
                    bufferData.filledSize = mFilledSize
                    sinGeneratorCallback.freeGenBuffer(bufferData)
                }
                mFilledSize = 0

            }
        }
    }

    companion object {

        private val TAG = "SinGenerator"

        private val STATE_START = 1
        private val STATE_STOP = 2

        // 2^8时的峰值
        val BITS_8 = 128
        // 默认为2^16时的峰值
        val BITS_16 = 32768

        // 采样率
        val SAMPLE_RATE_8 = 8000
        val SAMPLE_RATE_11 = 11250
        val SAMPLE_RATE_16 = 16000

        val UNIT_ACCURACY_1 = 4
        val UNIT_ACCURACY_2 = 8

        private val DEFAULT_BITS = BITS_8
        private val DEFAULT_SAMPLE_RATE = SAMPLE_RATE_8
        private val DEFAULT_BUFFER_SIZE = 1024
    }
}
